<template>
    <div>
        <el-row :gutter="20" style="height: 100%; margin: 0">
            <!--部门数据-->
            <el-col :span="4" :xs="24" style="margin-top: 8px">
                <div class="head-container">
                    <el-input v-model="deptName" placeholder="请输入部门名称" clearable prefix-icon="Search" style="margin-bottom: 20px" />
                </div>
                <div class="head-container">
                    <el-tree :data="deptOptions" :props="{ label: 'label', children: 'children' }" :expand-on-click-node="false" :filter-node-method="filterNode" ref="deptTreeRef" node-key="id" highlight-current default-expand-all @node-click="handleNodeClick" />
                </div>
            </el-col>
            <!--用户数据-->
            <el-col :span="20" :xs="24" style="height: 100%">
                <VxeBasicTable ref="xGrid" @checkbox-change="handleSelectionChange" style="height: 100%" tableName="sys_user" :params="searchInfo">
                    <template #toolbar_buttons>
                        <el-row :gutter="10">
                            <el-col :span="1.5">
                                <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:user:add']">新增</el-button>
                            </el-col>
                            <el-col :span="1.5">
                                <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['system:user:edit']">修改</el-button>
                            </el-col>
                            <el-col :span="1.5">
                                <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:user:remove']">删除</el-button>
                            </el-col>
                            <el-col :span="1.5">
                                <el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['system:user:import']">导入</el-button>
                            </el-col>
                            <el-col :span="1.5">
                                <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:user:export']">导出</el-button>
                            </el-col>
                        </el-row>
                    </template>
                    <template #slotStatus="{ row }">
                        <vxe-switch v-model="row['status']" size="medium" open-value="0" close-value="1" :disabled="row.roleId !== 1 ? !proxy.$auth.hasPermi('system:user:edit') : true" @change="handleStatusChange(row)"></vxe-switch>
                    </template>
                    <template #action="{ row }">
                        <el-tooltip content="修改" placement="top" v-if="row.userId !== 1">
                            <el-button link type="primary" icon="Edit" @click="handleUpdate(row)" v-hasPermi="['system:user:edit']"></el-button>
                        </el-tooltip>
                        <el-tooltip content="删除" placement="top" v-if="row.userId !== 1">
                            <el-button link type="primary" icon="Delete" @click="handleDelete(row)" v-hasPermi="['system:user:remove']"></el-button>
                        </el-tooltip>
                        <el-tooltip content="重置密码" placement="top" v-if="row.userId !== 1">
                            <el-button link type="primary" icon="Key" @click="handleResetPwd(row)" v-hasPermi="['system:user:resetPwd']"></el-button>
                        </el-tooltip>
                        <el-tooltip content="分配角色" placement="top" v-if="row.userId !== 1">
                            <el-button link type="primary" icon="CircleCheck" @click="handleAuthRole(row)" v-hasPermi="['system:user:edit']"></el-button>
                        </el-tooltip>
                    </template>
                </VxeBasicTable>
            </el-col>
        </el-row>

        <!-- 添加或修改用户配置对话框 -->
        <el-dialog :title="title" v-model="open" width="600px" append-to-body>
            <el-form :model="form" :rules="rules" ref="userRef" label-width="80px">
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="用户昵称" prop="nickName">
                            <el-input v-model="form.nickName" placeholder="请输入用户昵称" maxlength="30" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="归属部门" prop="deptId">
                            <el-tree-select v-model="form.deptId" :data="deptOptions" :props="{ value: 'id', label: 'label', children: 'children' }" value-key="id" placeholder="请选择归属部门" check-strictly :render-after-expand="false" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="手机号码" prop="phonenumber">
                            <el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="邮箱" prop="email">
                            <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item v-if="form.userId == undefined" label="用户名称" prop="userName">
                            <el-input v-model="form.userName" placeholder="请输入用户名称" maxlength="30" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item v-if="form.userId == undefined" label="用户密码" prop="password">
                            <el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="用户性别">
                            <el-select v-model="form.sex" placeholder="请选择">
                                <el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="状态">
                            <el-radio-group v-model="form.status">
                                <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
                            </el-radio-group>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12">
                        <el-form-item label="岗位">
                            <el-select v-model="form.postIds" multiple placeholder="请选择">
                                <el-option v-for="item in postOptions" :key="item.postId" :label="item.postName" :value="item.postId" :disabled="item.status == 1"></el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="角色">
                            <el-select v-model="form.roleIds" multiple placeholder="请选择">
                                <el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="24">
                        <el-form-item label="备注">
                            <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
                        </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="submitForm">确 定</el-button>
                    <el-button @click="cancel">取 消</el-button>
                </div>
            </template>
        </el-dialog>

        <!-- 用户导入对话框 -->
        <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
            <el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
                <el-icon class="el-icon--upload">
                    <upload-filled />
                </el-icon>
                <div class="el-upload__text">
                    将文件拖到此处，或
                    <em>点击上传</em>
                </div>
                <template #tip>
                    <div class="el-upload__tip text-center">
                        <div class="el-upload__tip"> <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据 </div>
                        <span>仅允许导入xls、xlsx格式文件。</span>
                        <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板</el-link>
                    </div>
                </template>
            </el-upload>
            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="submitFileForm">确 定</el-button>
                    <el-button @click="upload.open = false">取 消</el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>

<script setup lang="ts" name="User">
    import { getCurrentInstance, ref, reactive, toRefs, watch } from "vue";
    import { useRouter } from "vue-router";
    import { getToken } from "@/utils/auth";
    import { changeUserStatus, pageUser, resetUserPwd, delUser, getUser, updateUser, addUser, deptTreeSelect } from "@/api/system/user";
    import { VxeGridInstance, VxeGridProps, VxeGridListeners } from "../../../../types/index";
    import XEUtils from "xe-utils";
    import VxeBasicTable from "@/components/ElementRender";
    import { removeObjectNull } from "@/utils";
    const router = useRouter();
    const { proxy } = getCurrentInstance() as any;
    const { sys_normal_disable, sys_user_sex } = proxy.useDict("sys_normal_disable", "sys_user_sex");

    const userList = ref([]);
    const open = ref(false);
    const loading = ref(true);
    const showSearch = ref(true);
    const ids = ref([]);
    const single = ref(true);
    const multiple = ref(true);
    const total = ref(0);
    const title = ref("");
    const deptName = ref("");
    const deptOptions = ref(undefined);
    const initPassword = ref(undefined);
    const postOptions = ref<any[]>([]);
    const roleOptions = ref<any[]>([]);
    const searchInfo = reactive<any>({
        deptId: 0,
    });
    /*** 用户导入参数 */
    const upload = reactive({
        // 是否显示弹出层（用户导入）
        open: false,
        // 弹出层标题（用户导入）
        title: "",
        // 是否禁用上传
        isUploading: false,
        // 是否更新已经存在的用户数据
        updateSupport: 0,
        // 设置上传的请求头部
        headers: { Authorization: "Bearer " + getToken() },
        // 上传的地址
        url: import.meta.env.VITE_APP_BASE_API + "/system/user/importData",
    });
    // 列显隐信息
    const columns = ref([
        { key: 0, label: `用户编号`, visible: true },
        { key: 1, label: `用户名称`, visible: true },
        { key: 2, label: `用户昵称`, visible: true },
        { key: 3, label: `部门`, visible: true },
        { key: 4, label: `手机号码`, visible: true },
        { key: 5, label: `状态`, visible: true },
        { key: 6, label: `创建时间`, visible: true },
    ]);

    const data = reactive<any>({
        form: {},
        queryParams: {
            page: {
                current: 1,
                size: 10,
            },
            userName: undefined,
            phonenumber: undefined,
            status: undefined,
            deptId: undefined,
        },
        rules: {
            userName: [
                { required: true, message: "用户名称不能为空", trigger: "blur" },
                {
                    min: 2,
                    max: 20,
                    message: "用户名称长度必须介于 2 和 20 之间",
                    trigger: "blur",
                },
            ],
            nickName: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
            password: [
                { required: true, message: "用户密码不能为空", trigger: "blur" },
                {
                    min: 5,
                    max: 20,
                    message: "用户密码长度必须介于 5 和 20 之间",
                    trigger: "blur",
                },
            ],
            email: [
                {
                    type: "email",
                    message: "请输入正确的邮箱地址",
                    trigger: ["blur", "change"],
                },
            ],
            phonenumber: [
                {
                    pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
                    message: "请输入正确的手机号码",
                    trigger: "blur",
                },
            ],
        },
    });

    const { queryParams, form, rules } = toRefs(data);

    /** 通过条件过滤节点  */
    const filterNode = (value: any, data: any) => {
        if (!value) return true;
        return data.label.indexOf(value) !== -1;
    };
    /** 根据名称筛选部门树 */
    watch(deptName, (val: any) => {
        proxy.$refs["deptTreeRef"].filter(val);
    });
    /** 查询部门下拉树结构 */
    function getDeptTree() {
        deptTreeSelect().then((response) => {
            deptOptions.value = response.data;
        });
    }

    const xGrid = ref({} as VxeGridInstance);

    const gridOptions = reactive<VxeGridProps>({
        border: true,
        resizable: true,
        showHeaderOverflow: true,
        showOverflow: true,
        highlightHoverRow: true,
        keepSource: true,
        id: "15",
        height: "auto",
        rowId: "userId",
        sortConfig: {
            trigger: "cell",
            remote: true,
        },
        filterConfig: {
            remote: true,
        },
        pagerConfig: {
            pageSize: 10,
            pageSizes: [5, 10, 15, 20, 50, 100, 200, 500, 1000],
            perfect: true,
        },
        formConfig: {
            titleWidth: 100,
            titleAlign: "right",
            items: [
                {
                    field: "userName",
                    title: "用户名称",
                    span: 5,
                    itemRender: { name: "$input", props: { placeholder: "请输入用户名称" } },
                },
                {
                    field: "phonenumber",
                    title: "手机号码",
                    span: 5,
                    itemRender: { name: "$input", props: { placeholder: "请输入手机号码" } },
                },
                {
                    field: "status",
                    title: "状态",
                    span: 5,
                    itemRender: {
                        name: "$select",
                        options: sys_normal_disable,
                    },
                },
                {
                    field: "createTime",
                    title: "创建时间",
                    span: 5,
                    itemRender: {
                        name: "ElDatePicker",
                        props: {
                            valueFormat: "YYYY-MM-DD",
                            type: "daterange",
                            rangeSeparator: "-",
                            startPlaceholder: "开始日期",
                            endPlaceholder: "结束日期",
                        },
                    },
                },
                {
                    itemRender: {
                        name: "$buttons",
                        children: [
                            {
                                props: {
                                    type: "submit",
                                    content: "查询",
                                    status: "primary",
                                },
                            },
                            {
                                props: {
                                    type: "reset",
                                    content: "重置",
                                },
                            },
                        ],
                    },
                },
            ],
        },
        toolbarConfig: {
            refresh: true,
            zoom: true,
            export: proxy.$auth.hasPermi("system:user:export"),
            import: proxy.$auth.hasPermi("system:user:import"),
            custom: true,
            slots: {
                buttons: "toolbar_buttons",
            },
        },
        rowConfig: {
            isCurrent: true,
        },
        checkboxConfig: {
            trigger: "row",
        },
        proxyConfig: {
            paramsChangeLoad: true, //额外的请求参数改变时是否重新请求数据
            seq: true, // 启用动态序号代理，每一页的序号会根据当前页数变化
            sort: true, // 启用排序代理，当点击排序时会自动触发 query 行为
            filter: true, // 启用筛选代理，当点击筛选时会自动触发 query 行为
            form: true, // 启用表单代理，当点击表单提交按钮时会自动触发 reload 行为
            // 对应响应结果 { result: [], page: { total: 100 } }
            props: {
                result: "rows", // 配置响应结果列表字段
                total: "total", // 配置响应结果总页数字段
            },
            ajax: {
                // 接收 Promise
                query: ({ page, sorts, filters, form, params }: any) => {
                    // 处理时间范围查询
                    const createTime = proxy.addDateRange({}, form.createTime, "createTime");
                    const queryParams: any = Object.assign({}, form, page, createTime, params);
                    // 处理排序条件
                    const orderByColumn = <Array<String>>[];
                    const isAsc = <Array<Boolean>>[];
                    sorts.forEach((m: any) => {
                        orderByColumn.push(m.field);
                        isAsc.push(m.order);
                    });
                    queryParams.orderByColumn = orderByColumn.join(",");
                    queryParams.isAsc = isAsc.join(",");
                    // 处理筛选条件
                    filters.forEach(({ property, values }: any) => {
                        queryParams[property] = values.join(",");
                    });
                    return pageUser({
                        ...removeObjectNull(queryParams),
                    }).then((response) => {
                        return response;
                    });
                },
            },
        },
        columns: [
            { type: "checkbox", width: 60 },
            {
                field: "userId",
                title: "用户编号",
                sortable: true,
            },
            {
                field: "userName",
                title: "用户名称",
                sortable: true,
            },
            {
                field: "nickName",
                title: "用户昵称",
                sortable: true,
            },
            {
                field: "dept.deptName",
                title: "部门",
                sortable: true,
            },
            {
                field: "phonenumber",
                title: "手机号码",
                sortable: true,
            },
            {
                field: "status",
                title: "状态",
                slots: {
                    default: "slotStatus",
                },
            },
            {
                field: "createTime",
                title: "创建时间",
                visible: false,
                sortable: true,
                formatter({ cellValue }: any) {
                    return XEUtils.toDateString(cellValue, "yyyy-MM-dd HH:ss:mm");
                },
            },
            {
                title: "操作",
                width: 150,
                align: "center",
                fixed: "right",
                slots: { default: "action" },
            },
        ],
    });

    /** 节点单击事件 */
    function handleNodeClick(data: any) {
        queryParams.value.deptId = data.id;
        searchInfo.deptId = data.id;
        // handleQuery();
    }
    /** 删除按钮操作 */
    function handleDelete(row: any) {
        const userIds = row.userId || ids.value;
        proxy.$modal
            .confirm('是否确认删除用户编号为"' + userIds + '"的数据项？')
            .then(function () {
                return delUser(userIds);
            })
            .then(() => {
                // getList();
                xGrid.value.commitProxy("reload");
                proxy.$modal.msgSuccess("删除成功");
            })
            .catch(() => {});
    }
    /** 导出按钮操作 */
    function handleExport() {
        proxy.download(
            "system/user/export",
            {
                ...queryParams.value,
                filename: "测试",
                userName: "测试用户",
                pager: {
                    size: 10,
                    current: 1,
                    total: 20,
                },
                ids: [1, 2],
            },
            `user_${new Date().getTime()}.xlsx`
        );
    }
    /** 用户状态修改  */
    function handleStatusChange(row: any) {
        let text = row.status === "0" ? "启用" : "停用";
        proxy.$modal
            .confirm('确认要"' + text + '""' + row.userName + '"用户吗?')
            .then(function () {
                return changeUserStatus(row.userId, row.status);
            })
            .then(() => {
                proxy.$modal.msgSuccess(text + "成功");
            })
            .catch(function () {
                row.status = row.status === "0" ? "1" : "0";
            });
    }
    /** 更多操作 */
    function handleCommand(command: any, row: any) {
        switch (command) {
            case "handleResetPwd":
                handleResetPwd(row);
                break;
            case "handleAuthRole":
                handleAuthRole(row);
                break;
            default:
                break;
        }
    }
    /** 跳转角色分配 */
    function handleAuthRole(row: any) {
        const userId = row.userId;
        router.push("/system/user-auth/role/" + userId);
    }
    /** 重置密码按钮操作 */
    function handleResetPwd(row: any) {
        proxy
            .$prompt('请输入"' + row.userName + '"的新密码', "提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                closeOnClickModal: false,
                inputPattern: /^.{5,20}$/,
                inputErrorMessage: "用户密码长度必须介于 5 和 20 之间",
            })
            .then(({ value }: any) => {
                resetUserPwd(row.userId, value).then((response) => {
                    proxy.$modal.msgSuccess("修改成功，新密码是：" + value);
                });
            })
            .catch(() => {});
    }
    /** 选择条数  */
    function handleSelectionChange(selection: any) {
        ids.value = selection.records.map((item: any) => item.userId);
        single.value = selection.records.length != 1;
        multiple.value = !selection.records.length;
    }
    /** 导入按钮操作 */
    function handleImport() {
        upload.title = "用户导入";
        upload.open = true;
    }
    /** 下载模板操作 */
    function importTemplate() {
        proxy.download("system/user/importTemplate", {}, `user_template_${new Date().getTime()}.xlsx`);
    }
    /**文件上传中处理 */
    const handleFileUploadProgress = (event: any, file: any, fileList: any) => {
        upload.isUploading = true;
    };
    /** 文件上传成功处理 */
    const handleFileSuccess = (response: any, file: any, fileList: any) => {
        upload.open = false;
        upload.isUploading = false;
        proxy.$refs["uploadRef"].handleRemove(file);
        proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true });
        // getList();
        xGrid.value.commitProxy("reload");
    };
    /** 提交上传文件 */
    function submitFileForm() {
        proxy.$refs["uploadRef"].submit();
    }
    /** 重置操作表单 */
    function reset() {
        form.value = {
            userId: undefined,
            deptId: undefined,
            userName: undefined,
            nickName: undefined,
            password: undefined,
            phonenumber: undefined,
            email: undefined,
            sex: undefined,
            status: "0",
            remark: undefined,
            postIds: [],
            roleIds: [],
        };
        proxy.resetForm("userRef");
    }
    /** 取消按钮 */
    function cancel() {
        open.value = false;
        reset();
    }
    /** 新增按钮操作 */
    function handleAdd() {
        reset();
        getUser().then((response: any) => {
            postOptions.value = response.posts;
            roleOptions.value = response.roles;
            open.value = true;
            title.value = "添加用户";
            form.value.password = initPassword.value;
        });
    }
    /** 修改按钮操作 */
    function handleUpdate(row: any) {
        reset();
        const userId = row.userId || ids.value;
        getUser(userId).then((response: any) => {
            form.value = response.data;
            postOptions.value = response.posts;
            roleOptions.value = response.roles;
            form.value.postIds = response.postIds;
            form.value.roleIds = response.roleIds;
            open.value = true;
            title.value = "修改用户";
            form.value.password = "";
        });
    }
    /** 提交按钮 */
    function submitForm() {
        proxy.$refs["userRef"].validate((valid: any) => {
            if (valid) {
                if (form.value.userId != undefined) {
                    updateUser(form.value).then((response) => {
                        proxy.$modal.msgSuccess("修改成功");
                        open.value = false;
                        // getList();
                        xGrid.value.commitProxy("reload");
                    });
                } else {
                    addUser(form.value).then((response) => {
                        proxy.$modal.msgSuccess("新增成功");
                        open.value = false;
                        // getList();
                        xGrid.value.commitProxy("reload");
                    });
                }
            }
        });
    }
    getDeptTree();
    // getList();
</script>
